package org.jsets.rpc.server;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ResponseFuture implements Future<Response> {
	@SuppressWarnings("unused")
	private final Request request; //请求
	private long timeout;  //超时时间
	private final Lock lock = new ReentrantLock(); //锁
	private final Condition synchronizer = lock.newCondition();
	private final long defaultTimeout = 1000; //默认超时时间
	private volatile Response response; //响应
	private volatile ResponseCallback callback; //响应回调
	
	/**
	 * 构造函数
	 * @param _request
	 */
	public ResponseFuture(Request _request) {
		this.request = _request;
	}

	@Override
	public Response get() throws InterruptedException, ExecutionException {
		if(!isDone()){
			long start = System.currentTimeMillis();
			lock.lock();
			try {
				while(!isDone()){
					synchronizer.await(defaultTimeout, TimeUnit.MILLISECONDS);  //阻塞线程
					if(isDone() || System.currentTimeMillis() - start > timeout)
						break;
				}
			} finally {
				lock.unlock();
			}
		}
		return null;
	}
	
	public void done(Response response){
		lock.lock();
		try {
			this.response = response;
			if(synchronizer != null)
				synchronizer.signal(); //唤醒线程
		} finally {
			lock.unlock();
		}
		invokeCallback();
	}
	

	private void invokeCallback() {
		lock.lock();
		try {
			if(this.callback != null){
				if(response != null){
					callback.success(response);
				}else
					callback.fail(new RuntimeException("response error"));
			}
				
		} finally {
			lock.unlock();
		}
	}

	@Override
	public Response get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
		// TODO Auto-generated method stub
		return null;
	}
	

	@Override
	public boolean cancel(boolean mayInterruptIfRunning) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isCancelled() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isDone() {
		// TODO Auto-generated method stub
		return false;
	}


}
